
#include <iostream>
#include <string.h>
#include "TransactionManager.h"
#include "RecoveryManager.h"
using namespace std;
using namespace Taller2::TransRec;

//#define LOG_ESCRIBIR

#ifdef LOG_ESCRIBIR
int main() {

	//IScheduler *Scheduler = 0;
	CScheduler Scheduler;
	TransactionManager *manager = TransactionManager::Instance(&Scheduler);

	if(manager)
	{
		char newObj[] = "Some data....";
		long long int ObjID = 10;
		int err;
		
		//10 transacciones
		int tID01,tID02,tID03,tID04,tID05,tID06,tID07,tID08,tID09,tID10;

		//30 objetos: 3 por transaccion:i=Insert, d:delete, u:Update; 
		long long int oID01i,oID01d, oID01u;
		long long int oID02i,oID02d, oID02u;
		long long int oID03i,oID03d, oID03u;
		long long int oID04i,oID04d, oID04u;
		long long int oID05i,oID05d, oID05u;
		long long int oID06i,oID06d, oID06u;
		long long int oID07i,oID07d, oID07u;
		long long int oID08i,oID08d, oID08u;
		long long int oID09i,oID09d, oID09u;
		long long int oID10i,oID10d, oID10u;

		oID01i=101;oID01d=201; oID01u=201;
		oID02i=102;oID02d=202; oID02u=202;
		oID03i=103;oID03d=203; oID03u=203;
		oID04i=104;oID04d=204; oID04u=204;
		oID05i=105;oID05d=205; oID05u=205;
		oID06i=106;oID06d=206; oID06u=206;
		oID07i=107;oID07d=207; oID07u=207;
		oID08i=108;oID08d=208; oID08u=208;
		oID09i=109;oID09d=209; oID09u=209;
		oID10i=110;oID10d=210; oID10u=210;

		char Obj01i[]="Obj. ID:101 INS ";char Obj01d[]="Obj. ID:201 DEL ";char Obj01u[]="Obj. ID:301 UPD ";
		char Obj02i[]="Obj. ID:102 INS ";char Obj02d[]="Obj. ID:202 DEL ";char Obj02u[]="Obj. ID:302 UPD ";
		char Obj03i[]="Obj. ID:103 INS ";char Obj03d[]="Obj. ID:203 DEL ";char Obj03u[]="Obj. ID:303 UPD ";
		char Obj04i[]="Obj. ID:104 INS ";char Obj04d[]="Obj. ID:204 DEL ";char Obj04u[]="Obj. ID:304 UPD ";
		char Obj05i[]="Obj. ID:105 INS ";char Obj05d[]="Obj. ID:205 DEL ";char Obj05u[]="Obj. ID:305 UPD ";
		char Obj06i[]="Obj. ID:106 INS ";char Obj06d[]="Obj. ID:206 DEL ";char Obj06u[]="Obj. ID:306 UPD ";
		char Obj07i[]="Obj. ID:107 INS ";char Obj07d[]="Obj. ID:207 DEL ";char Obj07u[]="Obj. ID:307 UPD ";
		char Obj08i[]="Obj. ID:108 INS ";char Obj08d[]="Obj. ID:208 DEL ";char Obj08u[]="Obj. ID:308 UPD ";
		char Obj09i[]="Obj. ID:109 INS ";char Obj09d[]="Obj. ID:209 DEL ";char Obj09u[]="Obj. ID:309 UPD ";
		char Obj10i[]="Obj. ID:110 INS ";char Obj10d[]="Obj. ID:210 DEL ";char Obj10u[]="Obj. ID:310 UPD ";

		cout << "CREANDO EL LOG ..." << endl;

		//las transacciones 1 a 4 hacen commit
		//las transacciones 5 a 7 hacen rollback
		//las transacciones 8 a 10 no terminan

		tID01=manager->BeginTransaction();													 //BEGIN 01
		manager->PreWrite(oID01i, NULL, 0, Obj01i, strlen(Obj01i)+1, tID01);				 //INS 01
		tID02=manager->BeginTransaction();													 //BEGIN 02
		manager->PreWrite(oID02i, NULL, 0, Obj02i, strlen(Obj02i)+1, tID02);				 //INS 02
		manager->PreWrite(oID01i, Obj01i, strlen(Obj01i)+1, Obj01u, strlen(Obj01u)+1, tID01);//UPD 01
		tID03=manager->BeginTransaction();													 //BEGIN 03
		manager->PreWrite(oID01d, Obj01d, strlen(Obj01d)+1, NULL, 0, tID01);				 //DEL 01
		manager->PreWrite(oID03i, NULL, 0, Obj03i, strlen(Obj03i)+1, tID03);				 //INS 03
		tID04=manager->BeginTransaction();													 //BEGIN 04
		manager->PreWrite(oID02i, Obj02i, strlen(Obj02i)+1, Obj02u, strlen(Obj02u)+1, tID02);//UPD 02
		manager->PreWrite(oID04i, NULL, 0, Obj04i, strlen(Obj04i)+1, tID04);				 //INS 04
		tID05=manager->BeginTransaction();													 //BEGIN 05
		manager->PreWrite(oID05i, NULL, 0, Obj05i, strlen(Obj05i)+1, tID05);				 //INS 05
		manager->PreWrite(oID03i, Obj03i, strlen(Obj03i)+1, Obj03u, strlen(Obj03u)+1, tID03);//UPD 03
		manager->PreWrite(oID02d, Obj02d, strlen(Obj02d)+1, NULL, 0, tID02);				 //DEL 02
		manager->CommitTransaction(tID01);													 //COMMIT 01
		manager->CommitTransaction(tID02);													 //COMMIT 02
		tID06=manager->BeginTransaction();													 //BEGIN 06
		manager->PreWrite(oID04i, Obj04i, strlen(Obj04i)+1, Obj04u, strlen(Obj04u)+1, tID04);//UPD 04
		tID07=manager->BeginTransaction();													 //BEGIN 07
		manager->PreWrite(oID06i, NULL, 0, Obj06i, strlen(Obj06i)+1, tID06);				 //INS 06
		manager->PreWrite(oID03d, Obj03d, strlen(Obj03d)+1, NULL, 0, tID03);				 //DEL 03
		manager->PreWrite(oID05i, Obj05i, strlen(Obj05i)+1, Obj05u, strlen(Obj05u)+1, tID05);//UPD 05
		manager->PreWrite(oID04d, Obj04d, strlen(Obj04d)+1, NULL, 0, tID04);				 //DEL 04
		manager->PreWrite(oID06i, Obj06i, strlen(Obj06i)+1, Obj06u, strlen(Obj06u)+1, tID06);//UPD 06
		tID08=manager->BeginTransaction();													 //BEGIN 08
		manager->PreWrite(oID07i, NULL, 0, Obj07i, strlen(Obj07i)+1, tID07);				 //INS 07
		tID09=manager->BeginTransaction();													 //BEGIN 09
		tID10=manager->BeginTransaction();													 //BEGIN 10
		manager->PreWrite(oID08i, NULL, 0, Obj08i, strlen(Obj08i)+1, tID08);				 //INS 08
		manager->CommitTransaction(tID03);													 //COMMIT 03
		manager->PreWrite(oID05d, Obj05d, strlen(Obj05d)+1, NULL, 0, tID05);				 //DEL 05
		err=manager->RollbackTransaction(tID05);											 //ROLLBACK 05
		manager->CommitTransaction(tID04);													 //COMMIT 04
		manager->PreWrite(oID09i, NULL, 0, Obj09i, strlen(Obj09i)+1, tID09);				 //INS 09
		manager->PreWrite(oID07i, Obj07i, strlen(Obj07i)+1, Obj07u, strlen(Obj07u)+1, tID07);//UPD 07
		manager->PreWrite(oID10i, NULL, 0, Obj10i, strlen(Obj10i)+1, tID10);				 //INS 10
		manager->PreWrite(oID08i, Obj08i, strlen(Obj08i)+1, Obj08u, strlen(Obj08u)+1, tID08);//UPD 08
		manager->PreWrite(oID06d, Obj06d, strlen(Obj06d)+1, NULL, 0, tID06);				 //DEL 06
		manager->PreWrite(oID07d, Obj07d, strlen(Obj07d)+1, NULL, 0, tID07);				 //DEL 07
//////// CHECKPOINT /////////////////////////////////////////////////////////////////////////////////
		manager->PreWrite(oID09i, Obj09i, strlen(Obj09i)+1, Obj09u, strlen(Obj09u)+1, tID09);//UPD 09
		manager->PreWrite(oID08d, Obj08d, strlen(Obj08d)+1, NULL, 0, tID08);				 //DEL 08
		manager->PreWrite(oID10i, Obj10i, strlen(Obj10i)+1, Obj10u, strlen(Obj10u)+1, tID10);//UPD 10
		manager->PreWrite(oID09d, Obj09d, strlen(Obj09d)+1, NULL, 0, tID09);				 //DEL 09
		manager->RollbackTransaction(tID06);												 //ROLLBACK 06
		manager->PreWrite(oID10d, Obj10d, strlen(Obj10d)+1, NULL, 0, tID10);				 //DEL 10
		manager->RollbackTransaction(tID07);												 //ROLLBACK 07

		
		TransactionManager::CloseTransactionManager();

		cout << "LOG CREADO" << endl;
	}else
	{
		cout << "No se pudo crear el Transaction Manager" << endl;
	};

	return 0;
}

#else

int main(int argc, char *argv[])
{
	int result;
	RecoveryManager *R;
	CScheduler sch;

	R=R->Instance(&sch);
	cout<<"RECOVERY..."<<endl;
	result=	R->Recover();

	if(IsSuccess(result))
		cout<<"RECOVERY FINALIZADO EXITOSAMENTE"<<endl;
	else
		cout<<"RECOVERY FINALIZADO CON ERROR:"<<result<<endl;

	return 0;
}
#endif
